// pages/im/imMessagelist/imMessagelist.js
import TIM from "../../../utils/imLibs/tim-wx";

import { userInfoBehavior } from "../../../behaviors/userInfo";
import { RecorderManager } from "../../../common/recorderManager";
import { authorizationBehavior } from "../../../behaviors/authorization";
import { debounce, dateFormat } from "../../../utils/utilsNew.js";
import p from "../../../utils/platform";
import api from "../../../common/api";
import { cooperationBehavior } from "../../../behaviors/cooperation";
import { SCOPE_RECORD } from "../../../behaviors/authorization";
import { getData, resetData } from "../../../models/transferData";
import { imBe } from "../../../behaviors/imBe";
import { gio, gioAuthReadedLog } from "../../../common/gioHandler";
import constant from "../../../common/constant";
const computedBehavior = require("miniprogram-computed");

const app = getApp();

let _this;

/**
 * 自定义消息
 * 1. exchange_phone 交换手机号 （该类型不用了）
 * 2. copy_house 复制房源信息
 *     request 请求方  response 回应方
 *     subId 请求的日志id   cooperationId合作房源id  delId房源代理id
 * 2. copy_house 复制房源信息
 * 3. card_house 房源卡片  extension 合作房源id
 * 4. complain_jjr 投诉经纪人
 * 5. auth_card 认证信息卡片
 * 6. card_new_house 房源访客列表过来的卡片
 *
 * 
 * isRead 别人发给我的消息，我是否读过
 * isPeerRead 我发给别人，别人是否读过
 */

// 录音管理实例
const recorderManager = new RecorderManager();
// 最长录音时间
const MAX_RECORDER_DURING = 60 * 1000;
// 音频播放实例
let audioContext;
// 初始化进入
let firstEnter;
// 时间展示的间隔
const TIME_SPACE = 30 * 60;
const OFFICIAL_HEIGHT = 42;
// 预备发送的房源卡片待办回调
let prepareCb = null

Page({
  behaviors: [userInfoBehavior, authorizationBehavior, computedBehavior, cooperationBehavior, imBe],

  /**
   * 页面的初始数据
   */
  data: {
    userID: "", //我在im中的id
    targetUserID: "", //当前联系的对方用户id
    targetUserProfile: {}, //对方信息
    messageList: [], //消息列表
    msgInput: "",
    nextReqMessageID: null, //下一页聊天历史消息
    isCompleted: true, //当前消息列表是否展示完
    conversationID: "", // 当前会话id
    audioUuid: null, //当前正在播放的音频id
    enterType: "text", //输入类型 'text','audio'
    sendReady: false,
    targetAvatar: "",
    mineAvatar: "",
    isStartRecord: false, //是否开始录音
    isCancelRecord: false, //是否取消本次录音
    touchStartClientY: 0, //起始y位置
    officialHeight: 0, //关注公众号高度
    alreadyFollowed: true, //是否已经关注公众号
    firstMsg: true, //打开聊天的第一条发送消息

    navHeight: 0,
    navTop: 0,
    safeAreaBottomHeight: 0,
    cooperationId: "", //合作房源id（发起合作才会有该id，历史会话进来则没有）
    ispop: "0", //是否弹窗了认证信息 1弹了
    entryType: "1",
    agentId: "", //对方id（房源方）
    isShowPrepareCard: false, //预备发送的房源卡片弹层
  },

  /**
   * 生命周期函数--监听页面加载
   * options = {
   *  unionid // 跟谁聊
   *  conversationid //会话id
   *  cooperationId // 合作房源id
   *  fromInfo ,//判别是否询问后才发送房源卡片
   * }
   */
  onLoad: function (options) {
    // 打开IM聊天的上级页面埋点
    if(options.pageFrom){
      gio(constant.conversationPageView, {
        [constant.PageFrom]: options.pageFrom,
      });
    }
    _this = this;
    firstEnter = true;

    this.scrollToBottom = debounce(this.scrollToBottom.bind(this), 200);
    recorderManager.init({
      onRecordStop: this.onRecordStop,
    });

    this.data.conversationID = options.conversationid;
    this.data.targetUserID = options.unionid;
    this.data.agentId = options.agentId;
    this.data.ispop = options.ispop;

    this.setData({
      cooperationId: options.cooperationId,
      isShowPrepareCard: options.fromInfo == 'visitorList'
    })

    /** 认证小卡片信息 */
    let authCardInfo = getData("authCardInfo");
    resetData("authCardInfo");

    // 订阅投诉事件
    app && app.eventBus && app.eventBus.on("complain_jjr", this.sendComplainJjr.bind(this, this.data.cooperationId));
    app.globalData.systemPromise.then(() => {
      this.setData({
        navHeight: app.globalData.navHeight,
        navTop: app.globalData.navTop,
        safeAreaBottomHeight: app.globalData.safeAreaBottomHeight,
      });
    });

    this.loginEnter(authCardInfo);
  },

  queryIsWeChatSubscription() {
    return new Promise((resolve, reject) => {
      api.isBatch(null, (res) => {
        if (res && res.data) {
          let data = res.data;
          this.setData({
            alreadyFollowed: data.content,
            officialHeight: data.content ? 0 : OFFICIAL_HEIGHT,
          });
        }
        resolve();
      });
    });
  },

  loginEnter(authCardInfo) {
    wx.showLoading({ title: "加载中..." });

    app.globalData.loginPromise
      // 公众号初始化
      .then(({ sessionUser }) => {
        this.addEvent();
        return this.queryIsWeChatSubscription().then(() => sessionUser);
      })
      // 我的账号校验
      .then((sessionUser) => {
        return this.$mineValid(sessionUser, () => wx.navigateBack()).then(() => {
          const { wechatUnionid } = sessionUser.extProps;
          this.setData({
            userID: wechatUnionid,
            mineAvatar: this.getAvatar(sessionUser),
          });

          return wechatUnionid;
        });
      })
      // im SDK切换带来的问题，判断对方im账号是否有效
      .then((wechatUnionid) => {
        return this.$targetUserVerify(wechatUnionid, this.data.targetUserID, () => wx.navigateBack());
      })
      // 获取对方用户信息
      .then(this.getTargetUserInfo)
      // 初始化聊天列表
      .then(this.initMessage)
      // 客-看房后发起聊天
      .then((list) => {
        const { cooperationId, targetUserID, isShowPrepareCard } = this.data;
        if (cooperationId) {
          if (isShowPrepareCard) {
            authCardInfo && this.$authCardManage(list, targetUserID, authCardInfo);
            prepareCb = () => {
              this.$houseCardManage(list, targetUserID, cooperationId, true, 'card_new_house')
            }

          } else {
            this.$houseCardManage(list, targetUserID, cooperationId).then(() => {
              setTimeout(() => {
                authCardInfo && this.$authCardManage(list, targetUserID, authCardInfo);
              }, 1000);
            });
          }
        }

        // 埋点已读他人发过来的认证卡片
        this.authReadedLog(list);
      })
      .then(() => {
        wx.hideLoading();
      })
      .catch((error) => {
        wx.hideLoading();
        console.error(error);
      });
  },

  authReadedLog(list) {
    const msg = list.find((v) => v.payload.data === "auth_card" && v.to === this.data.userID && !v.isRead);
    if (msg) {
      const { mobile, nick } = this.data.targetUserProfile;
      gioAuthReadedLog(mobile, nick);
    }
  },

  getTargetUserInfo() {
    return this.getAuthenticatedInfoByUnionid(this.data.targetUserID).then((profile) => {
      this.setData({
        targetAvatar: profile.avatar,
        targetUserProfile: profile,
      });
    });
  },

  initMessage() {
    if (this.data.conversationID) {
      return this.getMessageList();
    } else {
      return this.$getConversationList(this.data.targetUserID)
        .then((id) => {
          this.data.conversationID = id;
          return this.getMessageList();
        })
        .catch((v) => {
          return Promise.resolve([]);
        });
    }
  },

  handleOfficial() {
    let url = "https://mp.weixin.qq.com/s/BY7_GPRG92cO-ZAFCOKetA";
    wx.navigateTo({ url: `/pages/webView/webView?webViewUrl=${url}` });
  },

  // 发送投诉信息
  sendComplainJjr(cooperationId) {
    let message = app.timControl.createCustomMessage(this.data.targetUserID, {
      data: "complain_jjr",
      description: "request",
      extension: JSON.stringify({ cooperationId }),
    });
    return this.imSendMessage(message);
  },

  // 获取消息列表
  getMessageList() {
    if (!this.data.conversationID) throw Error("conversationID为空");

    return app.timControl
      .getMessageList({
        conversationID: this.data.conversationID, //会话列表传递过来的参数
        count: this.data.singleCount,
        nextReqMessageID: this.data.nextReqMessageID,
      })
      .then(({ data }) => {
        // console.log("%c 获取消息列表getMessageList", "color: red", data);
        const messageList = data.messageList; // 消息列表。
        const nextReqMessageID = data.nextReqMessageID; // 用于续拉，分页续拉时需传入该字段。
        const isCompleted = data.isCompleted; // 表示是否已经拉完所有消息。
        this.data.nextReqMessageID = isCompleted ? null : nextReqMessageID;
        this.setData({ isCompleted });
        let list = messageList.concat(this.data.messageList);
        this.renderMessageList(list);

        app.timControl.setMessageRead(this.data.conversationID);

        this.scrollToBottom();
        return Promise.resolve(list);
      });
  },

  // 渲染消息列表，填上时间
  renderMessageList(list) {
    const userID = this.data.userID;
    list = list.filter(({ from, payload }) => {
      const { data, description } = payload;
      if (data !== "complain_jjr") return true;
      // 投诉信息对方不可看到
      return description === "request" && from === userID;
    });

    list.forEach((v) => {
      v._time = v._time || dateFormat(v.time * 1000, { showHourMin: true });
      if (v.type == "TIMCustomElem") {
        if (typeof v.payload.extension === "string" && v.payload.extension[0] === "{") {
          Object.assign(v.payload, JSON.parse(v.payload.extension));
        }
      }
    });

    if (list.length > 0) {
      list.reduce((baseTime, ele, index) => {
        let time = ele.time;
        if (index == 0) {
          ele.showTime = true;
        } else {
          let bool = time - baseTime > TIME_SPACE;
          ele.showTime = ele.showTime || bool;
          baseTime = bool ? time : baseTime;
        }

        return baseTime;
      }, list[0].time);
    }

    // console.log("%c 消息渲染===>>", "color: green", list);
    this.setData({
      messageList: list,
    });
  },

  // 发送消息
  imSendMessage(message) {
    return app.timControl
      .sendMessage(message)
      .then(({ data }) => {
        console.log("%c 发送消息成功sendMessage", "color: red", data.message.isPeerRead, data);
        let message = data.message;
        if (!this.data.conversationID) {
          this.data.conversationID = message.conversationID;
        }
        this.$gzhMessageHandler(message);
        this.renderMessageList(this.data.messageList.concat(message));
        this.scrollToBottom();
      })
      .catch((imError) => {
        console.error("发送消息sendMessage", imError);
      });
  },

  // 接受消息
  onMessageReceived(e) {
    let list = e.data.filter((v) => _this.data.conversationID == v.conversationID);

    wx.nextTick(() => {
      _this.refreshMessageToRead();
    });

    _this.renderMessageList(_this.data.messageList.concat(list));
    app.timControl.setMessageRead(_this.data.conversationID);
    _this.scrollToBottom();
  },

  refreshMessageToRead() {
    this.data.messageList.forEach((v, i) => {
      if (v.from !== this.data.userID) return;
      if (!v.isPeerRead) {
        this.setData({
          ["messageList[" + i + "].isPeerRead"]: true,
        });
      }
    });
  },

  // 输入框输入时出发
  handleInput(e) {
    this.setData({
      msgInput: e.detail.value,
      sendReady: !!e.detail.value,
    });
  },

  handleSendMsg() {
    if (!this.data.sendReady) return;
    let message = app.timControl.createTextMessage(this.data.targetUserID, this.data.msgInput);
    this.imSendMessage(message);
    setTimeout(() => {
      this.handleInput({ detail: { value: "" } });
    }, 100);
  },

  // 选择图片
  handleSelectImg(e) {
    wx.chooseImage({
      sourceType: ["album"], // 从相册选择
      count: 1, // 只选一张，目前 SDK 不支持一次发送多张图片
      success: (res) => {
        let message = app.timControl.createImageMessage(this.data.targetUserID, res);
        this.imSendMessage(message);
      },
    });
  },

  // 开始录音
  handleStartRecord(e) {
    this.data.touchStartClientY = e.touches[0].clientY;
    this.data.isCancelRecord = false;
    this.setData({ isStartRecord: true });
    recorderManager.start();
    wx.showToast({
      title: "上滑取消发送",
      image: "../images/audio.png",
      duration: MAX_RECORDER_DURING,
    });
  },
  // 结束录音
  handleStopRecord(e) {
    this.setData({ isStartRecord: false });
    wx.hideToast();
    recorderManager.stop();
  },

  handleTouchMove(e) {
    if (Math.abs(this.data.touchStartClientY - e.touches[0].clientY) > 50) {
      this.data.isCancelRecord = true;
      wx.showToast({
        title: "松开，取消发送",
        image: "../images/songkai.png",
      });
    }
  },

  // 录音结束监听函数
  onRecordStop(res) {
    if (this.data.isCancelRecord) {
      return wx.showToast({ icon: "none", title: "已取消发送" });
    }
    let message = app.timControl.createAudioMessage(this.data.targetUserID, res);
    this.imSendMessage(message);
  },

  getAudio() {
    if (!audioContext) {
      audioContext = wx.createInnerAudioContext();
      audioContext.onStop(() => {
        this.setData({ audioUuid: null });
      });

      audioContext.onEnded(() => {
        this.setData({ audioUuid: null });
      });
    }

    return audioContext;
  },

  // 播放音频
  handlePlay(e) {
    let { url, uuid } = e.detail;
    let audioContext = this.getAudio();
    if (this.data.audioUuid) {
      this.setData({ audioUuid: null });
      return audioContext.stop();
    }
    this.setData({
      audioUuid: uuid,
    });
    audioContext.src = url;
    audioContext.play();
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    if (this.data.isCompleted) {
      wx.stopPullDownRefresh();
      wx.showToast({ icon: "none", title: "无更多消息" });
      return;
    }

    this.getMessageList().then(() => {
      wx.stopPullDownRefresh();
    });
  },

  handleLoadImage() {
    this.scrollToBottom();
  },

  // 自动滚动页面到底部
  scrollToBottom() {
    wx.createSelectorQuery()
      .select("#page")
      .boundingClientRect((rect) => {
        if ((rect && rect.top < -20) || firstEnter) {
          firstEnter = false;
          wx.pageScrollTo({
            scrollTop: 9999,
          });
        }
      })
      .exec();
  },

  // 输入方式切换
  handleToggle() {
    if (this.data.enterType == "text") {
      this.getRecordAuthorize(SCOPE_RECORD).then(() => {
        this.setData({ enterType: "audio" });
      });
    } else {
      this.setData({ enterType: "text" });
    }
  },

  // 发起复制房源信息？
  handleCopyHouse(e) {
    let { cooperationId } = e.detail;
    api.recordAskCopyPhoneOrHouse(
      {
        houseOwnerUnionid: this.data.targetUserID,
        houseInviteUnionid: this.data.userID,
        type: 0,
      },
      ({ data }) => {
        let message = app.timControl.createCustomMessage(this.data.targetUserID, {
          data: "copy_house",
          description: "request",
          extension: JSON.stringify({ subId: data.content, cooperationId }),
        });
        this.imSendMessage(message);
      }
    );
  },

  handleResponse(e) {
    let { type, value, cooperationId } = e.detail;

    if (type == "copy_house") {
      let msg = this.checkHouseResponseHistory(cooperationId);
      if (value) {
        if (msg && msg.payload.delId) return wx.showToast({ icon: "none", title: "您已同意该请求" });
        api.agreeCopyDel({ cooperationId, askUnionId: this.data.targetUserID }, ({ data }) => {
          this.handleCopyResponse(data.content, cooperationId);
        });
      } else {
        if (msg) {
          return wx.showToast({ icon: "none", title: `您已${msg.payload.delId ? "同意" : "拒绝"}该请求` });
        }
        // 拒绝
        this.handleCopyResponse("", cooperationId);
      }
    } else if (type == "exchange_phone") {
      this.handlePhoneResponse(value);
    }
  },

  // 检查是否已经处理过该房源请求
  checkHouseResponseHistory(cooperationId) {
    const { userID } = this.data;
    return this.data.messageList.find((item) => {
      if (
        item.type == "TIMCustomElem" &&
        item.from == userID &&
        item.payload.data == "copy_house" &&
        item.payload.description == "response" &&
        item.payload.cooperationId == cooperationId
      ) {
        return true;
      }
    });
  },

  // 复制房源处理
  handleCopyResponse(value = "", cooperationId) {
    let message = app.timControl.createCustomMessage(this.data.targetUserID, {
      data: "copy_house",
      description: "response",
      extension: JSON.stringify({ delId: value, cooperationId }), // 房源的delid，拒绝则为""
    });
    this.imSendMessage(message);
  },

  // 交换手机号处理
  handlePhoneResponse(value) {
    let message = app.timControl.createCustomMessage(this.data.targetUserID, {
      data: "exchange_phone",
      description: "response",
      extension: JSON.stringify({ agree: value ? "yes" : "no" }),
    });
    this.imSendMessage(message);
  },

  // 打给他
  handleCallTa() {
    const { targetUserProfile} = this.data;
    this.setData({
      isVmShow:true,
      toUserId:targetUserProfile.id
    })
  },
  handleVmVisible(e) {
    this.setData({
      isVmShow: e.detail.visible
    });
  },

  handleBack() {
    if (getCurrentPages().length > 1) {
      p.navigateBack();
    } else {
      wx.redirectTo({ url: "/pages/index/index" });
    }
  },

  onSdkNotReady() {
    app.timControl
      .sdkReadyAndNext(_this.data.userID)
      .then(() => {
        _this.data.messageList = [];
        _this.data.nextReqMessageID = null;
        if (_this.data.conversationID) {
          return _this.getMessageList();
        } else {
          return _this
            .$getConversationList(_this.data.targetUserID)
            .then((id) => {
              _this.data.conversationID = id;
              return _this.getMessageList();
            })
            .catch((v) => {
              return Promise.resolve([]);
            });
        }
      })
      .catch(() => {
        wx.navigateBack();
        return Promise.reject();
      });
  },

  addEvent() {
    app && app.timControl && app.timControl.eventBus.on(TIM.EVENT.MESSAGE_RECEIVED, this.onMessageReceived);
    app && app.timControl && app.timControl.eventBus.on(TIM.EVENT.SDK_NOT_READY, this.onSdkNotReady);
  },
  removeEvent() {
    app && app.timControl && app.timControl.eventBus.off(TIM.EVENT.MESSAGE_RECEIVED, this.onMessageReceived);
    app && app.timControl && app.timControl.eventBus.off(TIM.EVENT.SDK_NOT_READY, this.onSdkNotReady);
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    this.removeEvent();
    audioContext && audioContext.stop();

    app && app.eventBus && app.eventBus.off("complain_jjr");
    prepareCb = null

    if (this.data.messageList.length) {
      api.updateCooperationTalkingTime({
        unionIdOne: this.data.userID,
        unionIdTwo: this.data.targetUserID,
        lastTime: this.data.messageList[this.data.messageList.length - 1].time,
      });
    }
  },

  handleHidePrepareCard() {
    this.setData({
      isShowPrepareCard: false
    })
  },

  // 发送认证卡片（因为需要用户点击触发，且在进入页面后即可确定行为内容）
  handleSendPrepareCard() {
    this.handleHidePrepareCard()
    prepareCb && prepareCb()
    prepareCb = null
  },
  noop(){}
});
